<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:am="http://ns.medbiq.org/activitymodel/v1/"
 xmlns:dam="http://ns.medbiq.org/dataavailabilitymodel/v1/"
 xmlns:ims="http://www.imsglobal.org/xsd/imscp_v1p1"
 xmlns:vpd="http://ns.medbiq.org/virtualpatientdata/v1/"
 xmlns:java="http://xml.apache.org/xalan/java"
 exclude-result-prefixes="am dam vpd ims java"
 >
	<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
	<!-- default schema version -->
	<xsl:param name="schema-version-param" select="'1.0'"/>
	<xsl:variable name="schema-version"><xsl:choose>
		<xsl:when test="$schema-version-param = ''">1.0</xsl:when>
		<xsl:otherwise><xsl:value-of select="$schema-version-param"/></xsl:otherwise>
	</xsl:choose></xsl:variable>
	<xsl:param name="basedir" select="'.'"/>
	<xsl:param name="schemas-basedir-param" select="'.'"/>
	<xsl:variable name="schemas-basedir"><xsl:choose>
		<xsl:when test="$schemas-basedir-param = ''"><xsl:value-of select="$basedir"/></xsl:when>
		<xsl:otherwise><xsl:value-of select="$schemas-basedir-param"/></xsl:otherwise>
	</xsl:choose></xsl:variable>
	<xsl:variable name="a" select="document(concat($basedir,'/activitymodel.xml'))"/>
	<xsl:variable name="d" select="document(concat($basedir,'/dataavailabilitymodel.xml'))"/>
	<xsl:variable name="v" select="document(concat($basedir,'/virtualpatientdata.xml'))"/>
	<xsl:variable name="i" select="document(concat($basedir,'/imsmanifest.xml'))"/>
	<xsl:variable name="sq">'</xsl:variable>
	   	
	
    <xsl:template match="/">
    
    <xsl:message>
     * Schema Version: <xsl:value-of select="$schema-version"/>
     * BaseDir: <xsl:value-of select="$basedir"/>
     * Schema-Basedir: <xsl:value-of select="$schemas-basedir"/>    
    </xsl:message>    
    
     <xsl:variable name="files" select="java:campus.evip.XalanUtils.getFilesAsXML ($basedir)"/>
     <tests>
     
      <message name="Version">XSLT Test Suite $Revision: 24 $ ($Date: 2010-06-01 08:48:45 +0000 (Tue, 01 Jun 2010) $</message>     
     
      <message name="Number of activity nodes"><xsl:value-of select="count($a//am:ActivityNode)"/></message>
      <message name="Number of dam nodes"><xsl:value-of select="count($d//dam:DAMNode)"/></message>
      
      <xsl:message>Test: Schema Validation of virtualpatientdata.xml <xsl:value-of select="$schema-version"/></xsl:message>
      <test>
       <xsl:attribute name="name">Schema Validation of virtualpatientdata.xml (<xsl:value-of select="$schema-version"/>)</xsl:attribute>
        <output>
          <xsl:variable name="errors" select="java:campus.evip.XalanUtils.validate (concat ($basedir, '/virtualpatientdata.xml'), concat ($schemas-basedir, '/schemas/',$schema-version,'/virtualpatientdata.xsd'))"/>
          <xsl:for-each select="$errors//error">
              <xsl:value-of select="@localized-message"/>
              <xsl:if test="position() != 1"><xsl:text>
</xsl:text>
              </xsl:if>
          </xsl:for-each>
        </output>
      </test>
      
      <xsl:message>Test: Schema Validation of dataavailabilitymodel.xml (<xsl:value-of select="$schema-version"/>)</xsl:message>
      <test>
       <xsl:attribute name="name">Schema Validation of dataavailabilitymodel.xml (<xsl:value-of select="$schema-version"/>)</xsl:attribute>
        <output>
          <xsl:variable name="errors" select="java:campus.evip.XalanUtils.validate (concat ($basedir, '/dataavailabilitymodel.xml'), concat ($schemas-basedir, '/schemas/',$schema-version,'/dataavailabilitymodel.xsd'))"/>
          <xsl:for-each select="$errors//error">
              <xsl:value-of select="@localized-message"/>
              <xsl:if test="position() != 1"><xsl:text>
</xsl:text>
              </xsl:if>
          </xsl:for-each>
        </output>
      </test>

      <xsl:message>Test: Schema Validation of activitymodel.xml (<xsl:value-of select="$schema-version"/>)</xsl:message>
      <test>
       <xsl:attribute name="name">Schema Validation of activitymodel.xml (<xsl:value-of select="$schema-version"/>)</xsl:attribute>
        <output>
          <xsl:variable name="errors" select="java:campus.evip.XalanUtils.validate (concat ($basedir, '/activitymodel.xml'), concat ($schemas-basedir, '/schemas/',$schema-version,'/activitymodel.xsd'))"/>
          <xsl:for-each select="$errors//error">
              <xsl:value-of select="@localized-message"/>
              <xsl:if test="position() != 1"><xsl:text>
</xsl:text></xsl:if>
          </xsl:for-each>
        </output>
      </test>

      <xsl:message>Test: Schema Validation of imsmanifest.xml</xsl:message>
      <test name="Schema Validation of imsmanifest.xml">
        <output>
          <xsl:variable name="errors" select="java:campus.evip.XalanUtils.validate (concat ($basedir, '/imsmanifest.xml'), concat ($schemas-basedir, '/schemas/imscp_v1p1.xsd'))"/>
          <!-- There are some errors reported from the schema file which are just ignored -->
          <xsl:for-each select="$errors//error[not(contains(@message,'attr.base')) and not(contains(@message,'xml:base')) and not(contains(@message,'manifestType'))]">
              <xsl:value-of select="@localized-message"/>
              <xsl:if test="position() != 1"><xsl:text>
</xsl:text>
              </xsl:if>
          </xsl:for-each>
        </output>
      </test>

      <xsl:message>Test: DAMNodes not accessed by ActivityNodes</xsl:message>
      <test name="DAMNodes not accessed by ActivityNodes">
      <output>
        <xsl:for-each select="$d//dam:DAMNode">
         <xsl:variable name="id" select="@id"/>
         <xsl:if test="not($a//am:ActivityNode[$id=substring-before(substring-after(am:Content/text(),$sq),$sq)]) and not($d//dam:DAMNode[@id=$id])">
DAMNode-ID: <xsl:value-of select="@id"/></xsl:if>
         </xsl:for-each>
         </output>
       </test>

      <xsl:message>Test: ActivityNodes with wrong references to DAMNodes</xsl:message>
       <test name="ActivityNodes with wrong references to DAMNodes">
        <output>
        <xsl:for-each select="$a//am:ActivityNode">
        <xsl:variable name="id" select="substring-before(substring-after(am:Content/text(),$sq),$sq)"/>
        <xsl:if test="not($d//dam:DAMNode[@id=$id])">
          ActivityNode-ID: <xsl:value-of select="@id"/> (wrong id: <xsl:value-of select="$id"/>)</xsl:if>
         </xsl:for-each>
        </output>
       </test>

      <xsl:message>Test: DAMNodeItem with wrong references in ItemPath</xsl:message>
       <test name="DAMNodeItem with wrong references in ItemPath">
        <output>
        <xsl:for-each select="$d//dam:DAMNodeItem[dam:ItemPath]">
          <xsl:variable name="id" select="substring-before(substring-after(dam:ItemPath/text(),$sq),$sq)"/>
          <xsl:if test="not($v//*[@id=$id]) and not($i//ims:resource[@identifier=$id]) and not(contains(dam:ItemPath,'XtensibleInfo'))">
DAMNode-ID: <xsl:value-of select="../@id"/>#<xsl:value-of select="position()"/> (wrong id: <xsl:value-of select="$id"/>)</xsl:if>
         </xsl:for-each>
        </output>
       </test>

      <xsl:message>Test: DAMNodeItem with wrong references in ItemComment</xsl:message>
       <test name="DAMNodeItem with wrong references in ItemComment">
        <output>
        <xsl:for-each select="$d//dam:DAMNodeItem[dam:ItemComment]">
          <xsl:variable name="id" select="substring-before(substring-after(dam:ItemComment/text(),$sq),$sq)"/>
          <xsl:if test="not($d//dam:DAMNode[@id=$id])">
DAMNode-ID: <xsl:value-of select="../@id"/>#<xsl:value-of select="position()"/> (wrong id: <xsl:value-of select="$id"/>)</xsl:if>
         </xsl:for-each>
        </output>
       </test>

      <xsl:message>Test: DAMNodeItem with reference to another, but undefined namespace</xsl:message>
      <test name="DAMNodeItem with reference to another, but undefined namespace">
        <output>
         <xsl:for-each select="$d//dam:DAMNodeItem[contains(dam:ItemPath/text(),':')]">
          <xsl:variable name="namespace-prefix"><xsl:call-template name="remove-preceding-path-items"><xsl:with-param name="text" select="substring-before(dam:ItemPath/text(),':')"/></xsl:call-template></xsl:variable>
           <xsl:if test="not(namespace::*[name()=$namespace-prefix])">
Namespace-prefix: <xsl:value-of select="$namespace-prefix"/> (ItemPath: <xsl:value-of select="normalize-space(dam:ItemPath)"/>)</xsl:if>
         </xsl:for-each>
        </output>
       </test>       
       <!--
      <xsl:message>Test: DAMNodeItem with reference to VPDText and display=ontrigger (which doesn't make sense)</xsl:message>
       <test type="warning" name="DAMNodeItem with reference to VPDText and display=ontrigger (which doesn't make sense)">
        <output>
        <xsl:for-each select="$d//dam:DAMNodeItem[@display='ontrigger' and contains(dam:ItemPath/text(),'VPDText')]">
DAMNode-ID: <xsl:value-of select="../@id"/>
         </xsl:for-each>
        </output>
       </test>       
       -->
      <xsl:message>Test: Unreferenced VPDText</xsl:message>
       <test name="Unreferenced VPDText">
        <output>
          <xsl:for-each select="$v//vpd:VPDText">
            <xsl:variable name="id" select="@id"/>
            <xsl:if test="not($d//dam:DAMNodeItem[contains(dam:ItemPath/text(), 'VPDText') and substring-before(substring-after(dam:ItemPath/text(),$sq),$sq)=$id])">
VPDText-ID: <xsl:value-of select="$id"/></xsl:if>
          </xsl:for-each>
        </output>
       </test>
       
      <xsl:message>Test: Unreferenced InterviewItem</xsl:message>
       <test name="Unreferenced InterviewItem">
        <output>
          <xsl:for-each select="$v//vpd:InterviewItem">
            <xsl:variable name="id" select="@id"/>
            <xsl:if test="not($d//dam:DAMNodeItem[contains(dam:ItemPath/text(), 'InterviewItem') and substring-before(substring-after(dam:ItemPath/text(),$sq),$sq)=$id])">
InterviewItem-ID: <xsl:value-of select="$id"/></xsl:if>
          </xsl:for-each>
        </output>
       </test>

      <xsl:message>Test: Unreferenced PhysicalExam</xsl:message>
       <test name="Unreferenced PhysicalExam">
        <output>
          <xsl:for-each select="$v//vpd:PhysicalExam">
            <xsl:variable name="id" select="@id"/>
            <xsl:if test="not($d//dam:DAMNodeItem[contains(dam:ItemPath/text(), 'PhysicalExam') and substring-before(substring-after(dam:ItemPath/text(),$sq),$sq)=$id])">
PhysicalExam-ID: <xsl:value-of select="$id"/></xsl:if>
          </xsl:for-each>
        </output>
       </test>

      <xsl:message>Test: Unreferenced DiagnosticTest</xsl:message>
       <test name="Unreferenced DiagnosticTest">
        <output>
          <xsl:for-each select="$v//vpd:DiagnosticTest">
            <xsl:variable name="id" select="@id"/>
            <xsl:if test="not($d//dam:DAMNodeItem[contains(dam:ItemPath/text(), 'DiagnosticTest') and substring-before(substring-after(dam:ItemPath/text(),$sq),$sq)=$id])">
DiagnosticTest-ID: <xsl:value-of select="$id"/></xsl:if>
          </xsl:for-each>
        </output>
       </test>

      <xsl:message>Test: Unreferenced Diagnosis</xsl:message>
       <test name="Unreferenced Diagnosis">
        <output>
          <xsl:for-each select="$v//vpd:Diagnosis">
            <xsl:variable name="id" select="@id"/>
            <xsl:if test="not($d//dam:DAMNodeItem[contains(dam:ItemPath/text(), 'Diagnosis') and substring-before(substring-after(dam:ItemPath/text(),$sq),$sq)=$id])">
Diagnosis-ID: <xsl:value-of select="$id"/></xsl:if>
          </xsl:for-each>
        </output>
       </test>
       
      <xsl:message>Test: Unreferenced Intervention</xsl:message>
       <test name="Unreferenced Intervention">
        <output>
          <xsl:for-each select="$v//vpd:Intervention">
            <xsl:variable name="id" select="@id"/>
            <xsl:if test="not($d//dam:DAMNodeItem[contains(dam:ItemPath/text(), 'Intervention') and substring-before(substring-after(dam:ItemPath/text(),$sq),$sq)=$id])">
Intervention-ID: <xsl:value-of select="$id"/></xsl:if>
          </xsl:for-each>
        </output>
       </test>

      <xsl:message>Test: Wrong Media References</xsl:message>
       <test name="Wrong Media References">
        <output>
          <xsl:for-each select="$d//dam:DAMNodeItem[contains(dam:ItemPath,'/manifest/resources/resource')]">
            <xsl:variable name="id" select="substring-before(substring-after(dam:ItemPath/text(),$sq),$sq)"/>
            <xsl:if test="not($i//ims:resource[@identifier=$id]) and not($v//vpd:Media[contains(@refPath,concat($sq,$id,$sq))])">
Resource-ID: <xsl:value-of select="$id"/></xsl:if>
          </xsl:for-each>
        </output>
       </test>
       
      <xsl:message>Test: Duplicated  IDs</xsl:message>
       <test name="Duplicated  IDs">
         <output>
           <xsl:for-each select="$v//*[@id]">
            <xsl:variable name="id" select="@id"/>
            <xsl:if test="count($v//*[@id=$id]) &gt; 1">
virtualpatientdata.xml: Multiple ID <xsl:value-of select="$id"/>            
            </xsl:if>
           </xsl:for-each>
           <xsl:for-each select="$d//*[@id]">
            <xsl:variable name="id" select="@id"/>
            <xsl:if test="count($d//*[@id=$id]) &gt; 1">
dataavailibilitymodel.xml: Multiple ID <xsl:value-of select="$id"/>            
            </xsl:if>
           </xsl:for-each>
           <xsl:for-each select="$a//*[@id]">
            <xsl:variable name="id" select="@id"/>
            <xsl:if test="count($a//*[@id=$id]) &gt; 1">
activitymodel.xml: Multiple ID <xsl:value-of select="$id"/>            
            </xsl:if>
           </xsl:for-each>
         </output>
       </test>



        <!-- File checking -->

        <!--
        <test name="Missing Media files">
         <output>
          <xsl:for-each select="$d//dam:DAMNodeItem[contains(dam:ItemPath,'/manifest/resources/resource')]">
            <xsl:variable name="id" select="substring-before(substring-after(dam:ItemPath/text(),$sq),$sq)"/>
            <xsl:variable name="resource-href" select="$i//ims:resource[@identifier=$id]/@href"/>
            <xsl:if test="not($files//file[@full-path=$resource-href])">
Resource-ID: <xsl:value-of select="$id"/></xsl:if>
          </xsl:for-each>           
          </output>
        </test>
        -->
        
       <xsl:message>Test: Files not referenced by imsmanifest.xml</xsl:message>
        <test name="Files not referenced by imsmanifest.xml">
         <output>
          <xsl:for-each select="$files//file">
           <xsl:if test="not($i//ims:resource[@href=current()/@full-path])">
File: <xsl:value-of select="@full-path"/>
           </xsl:if>
          </xsl:for-each>
         </output>
        </test>
        
       <xsl:message>Test: Not found files referenced by imsmanifest.xml</xsl:message>
        <test name="Not found files referenced by imsmanifest.xml">
          <output>
           <xsl:for-each select="$i//ims:resource">
             <xsl:if test="not($files//file[@full-path=current()/@href])">
Resource-ID: <xsl:value-of select="@identifier"/> (points to <xsl:value-of select="@href"/>)</xsl:if>
           </xsl:for-each>
          </output>
        </test>
       
     </tests>

    </xsl:template>
    
    <!-- Removes /a/b/c/ from /a/b/c/d -->
    <xsl:template name="remove-preceding-path-items">
      <xsl:param name="text" select="''"/>
      <xsl:param name="separator" select="'/'"/>
      <xsl:choose>
		<xsl:when test="contains($text, $separator)">
		   <xsl:call-template name="remove-preceding-path-items">
		     <xsl:with-param name="text" select="substring-after($text, $separator)"/>
		     <xsl:with-param name="separator" select="$separator"/>
		   </xsl:call-template>
		</xsl:when>
		<xsl:otherwise><xsl:value-of select="$text"/></xsl:otherwise>
	  </xsl:choose>
    </xsl:template>
    	
</xsl:stylesheet>
